package com.reactim.message.performance;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;

/**
 * 性能测试运行器
 */
@Slf4j
@SpringBootTest
@ActiveProfiles("integration-test")
@RequiredArgsConstructor
public class PerformanceTestRunner {

    @Autowired
    private PerformanceTestService performanceTestService;

    /**
     * 运行完整的性能测试套件
     */
    @Test
    public void runFullPerformanceTestSuite() {
        log.info("=== 开始执行完整性能测试套件 ===");
        
        try {
            PerformanceTestService.PerformanceTestResult result = 
                performanceTestService.runFullPerformanceTest();
            
            // 输出测试结果
            printTestResults(result);
            
            log.info("=== 性能测试套件执行完成 ===");
            
        } catch (Exception e) {
            log.error("性能测试套件执行失败", e);
            throw e;
        }
    }

    /**
     * 运行延迟测试
     */
    @Test
    public void runLatencyTest() {
        log.info("=== 开始执行延迟测试 ===");
        
        PerformanceTestService.LatencyTestResult result = 
            performanceTestService.runLatencyTest();
        
        printLatencyResults(result);
        
        log.info("=== 延迟测试完成 ===");
    }

    /**
     * 运行吞吐量测试
     */
    @Test
    public void runThroughputTest() {
        log.info("=== 开始执行吞吐量测试 ===");
        
        PerformanceTestService.ThroughputTestResult result = 
            performanceTestService.runThroughputTest();
        
        printThroughputResults(result);
        
        log.info("=== 吞吐量测试完成 ===");
    }

    /**
     * 运行并发测试
     */
    @Test
    public void runConcurrencyTest() throws InterruptedException {
        log.info("=== 开始执行并发测试 ===");
        
        PerformanceTestService.ConcurrencyTestResult result = 
            performanceTestService.runConcurrencyTest();
        
        printConcurrencyResults(result);
        
        log.info("=== 并发测试完成 ===");
    }

    /**
     * 运行负载测试
     */
    @Test
    public void runLoadTest() {
        log.info("=== 开始执行负载测试 ===");
        
        PerformanceTestService.LoadTestResult result = 
            performanceTestService.runLoadTest();
        
        printLoadResults(result);
        
        log.info("=== 负载测试完成 ===");
    }

    /**
     * 运行压力测试
     */
    @Test
    public void runStressTest() {
        log.info("=== 开始执行压力测试 ===");
        
        PerformanceTestService.StressTestResult result = 
            performanceTestService.runStressTest();
        
        printStressResults(result);
        
        log.info("=== 压力测试完成 ===");
    }

    /**
     * 打印完整测试结果
     */
    private void printTestResults(PerformanceTestService.PerformanceTestResult result) {
        log.info("=== 性能测试结果汇总 ===");
        
        if (result.getLatencyResult() != null) {
            printLatencyResults(result.getLatencyResult());
        }
        
        if (result.getThroughputResult() != null) {
            printThroughputResults(result.getThroughputResult());
        }
        
        if (result.getConcurrencyResult() != null) {
            printConcurrencyResults(result.getConcurrencyResult());
        }
        
        if (result.getLoadResult() != null) {
            printLoadResults(result.getLoadResult());
        }
        
        if (result.getStressResult() != null) {
            printStressResults(result.getStressResult());
        }
    }

    /**
     * 打印延迟测试结果
     */
    private void printLatencyResults(PerformanceTestService.LatencyTestResult result) {
        log.info("--- 延迟测试结果 ---");
        log.info("测试次数: {}", result.getTestCount());
        
        if (result.getStoreLatencies() != null) {
            PerformanceTestService.LatencyStats stats = result.getStoreLatencies();
            log.info("存储操作延迟:");
            log.info("  平均: {:.2f} ms", stats.getAverage());
            log.info("  最小: {} ms", stats.getMin());
            log.info("  最大: {} ms", stats.getMax());
            log.info("  P50: {} ms", stats.getP50());
            log.info("  P95: {} ms", stats.getP95());
            log.info("  P99: {} ms", stats.getP99());
        }
        
        if (result.getRetrieveLatencies() != null) {
            PerformanceTestService.LatencyStats stats = result.getRetrieveLatencies();
            log.info("检索操作延迟:");
            log.info("  平均: {:.2f} ms", stats.getAverage());
            log.info("  最小: {} ms", stats.getMin());
            log.info("  最大: {} ms", stats.getMax());
            log.info("  P50: {} ms", stats.getP50());
            log.info("  P95: {} ms", stats.getP95());
            log.info("  P99: {} ms", stats.getP99());
        }
        
        if (result.getRemoveLatencies() != null) {
            PerformanceTestService.LatencyStats stats = result.getRemoveLatencies();
            log.info("移除操作延迟:");
            log.info("  平均: {:.2f} ms", stats.getAverage());
            log.info("  最小: {} ms", stats.getMin());
            log.info("  最大: {} ms", stats.getMax());
            log.info("  P50: {} ms", stats.getP50());
            log.info("  P95: {} ms", stats.getP95());
            log.info("  P99: {} ms", stats.getP99());
        }
    }

    /**
     * 打印吞吐量测试结果
     */
    private void printThroughputResults(PerformanceTestService.ThroughputTestResult result) {
        log.info("--- 吞吐量测试结果 ---");
        
        for (PerformanceTestService.ThroughputMeasurement measurement : result.getMeasurements()) {
            log.info("操作类型: {}", measurement.getOperationType());
            log.info("  操作数量: {}", measurement.getOperationCount());
            log.info("  总耗时: {} ms", measurement.getDurationMs());
            log.info("  吞吐量: {:.2f} ops/sec", measurement.getThroughput());
        }
    }

    /**
     * 打印并发测试结果
     */
    private void printConcurrencyResults(PerformanceTestService.ConcurrencyTestResult result) {
        log.info("--- 并发测试结果 ---");
        
        for (PerformanceTestService.ConcurrencyMeasurement measurement : result.getMeasurements()) {
            log.info("线程数: {}", measurement.getThreadCount());
            log.info("  每线程操作数: {}", measurement.getOperationsPerThread());
            log.info("  总操作数: {}", measurement.getTotalOperations());
            log.info("  成功操作数: {}", measurement.getSuccessCount());
            log.info("  失败操作数: {}", measurement.getErrorCount());
            log.info("  总耗时: {} ms", measurement.getDurationMs());
            log.info("  吞吐量: {:.2f} ops/sec", measurement.getThroughput());
            log.info("  成功率: {:.2f}%", 
                (double) measurement.getSuccessCount() / measurement.getTotalOperations() * 100);
        }
    }

    /**
     * 打印负载测试结果
     */
    private void printLoadResults(PerformanceTestService.LoadTestResult result) {
        log.info("--- 负载测试结果 ---");
        
        for (PerformanceTestService.LoadMeasurement measurement : result.getMeasurements()) {
            log.info("连接数: {}", measurement.getConnectionCount());
            log.info("  创建耗时: {} ms", measurement.getCreateTimeMs());
            log.info("  查询耗时: {} ms", measurement.getQueryTimeMs());
            log.info("  随机访问耗时: {} ms", measurement.getRandomAccessTimeMs());
            log.info("  实际在线数: {}", measurement.getActualOnlineCount());
            log.info("  平均每连接创建时间: {:.2f} ms", 
                (double) measurement.getCreateTimeMs() / measurement.getConnectionCount());
        }
    }

    /**
     * 打印压力测试结果
     */
    private void printStressResults(PerformanceTestService.StressTestResult result) {
        log.info("--- 压力测试结果 ---");
        
        for (PerformanceTestService.StressMeasurement measurement : result.getMeasurements()) {
            log.info("目标负载: {}", measurement.getTargetLoad());
            log.info("  实际负载: {}", measurement.getActualLoad());
            log.info("  耗时: {} ms", measurement.getDurationMs());
            log.info("  成功: {}", measurement.isSuccess());
            
            if (!measurement.isSuccess() && measurement.getErrorMessage() != null) {
                log.info("  错误信息: {}", measurement.getErrorMessage());
            }
            
            if (measurement.isSuccess()) {
                log.info("  负载达成率: {:.2f}%", 
                    (double) measurement.getActualLoad() / measurement.getTargetLoad() * 100);
            }
        }
    }
}